package com.jing.yao.modules.dict.item.service.impl;

import com.jing.yao.bean.KeyValue;
import com.jing.yao.cache.CacheHelper;
import com.jing.yao.cache.RedisKeyEnum;
import com.jing.yao.code.UserCode;
import com.jing.yao.component.constants.BaseOperationEnum;
import com.jing.yao.component.mapper.YaoBaseMapper;
import com.jing.yao.exception.BusinessExceptionBuilder;
import com.jing.yao.modules.dict.item.controller.param.DictItemParam;
import com.jing.yao.modules.dict.item.dao.DictItemMapper;
import com.jing.yao.modules.dict.item.dao.entity.DictItemEntity;
import com.jing.yao.modules.dict.item.service.DictItemService;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 数据字典项信息
 *
 * @author lr
 * @since 2019-07-31 10:50
 */
@Service
public class DictItemItemServiceImpl implements DictItemService {

    @Autowired
    private DictItemMapper dictItemMapper;


    @Autowired
    private CacheHelper cacheHelper;

    private static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    @Override
    public YaoBaseMapper<DictItemEntity> getMapper() {
        return dictItemMapper;
    }

    /**
     * 重写查询条件
     *
     * @param param 查询条件
     * @return
     */
    @Override
    public Wrapper<DictItemEntity> getWrapper(DictItemParam param) {
        QueryWrapper<DictItemEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dict_code", param.getDictCode());

        if (StringUtils.isNotBlank(param.getItemName())) {
            queryWrapper.like("item_name", param.getItemName());
        }
        return queryWrapper;
    }

    @Override
    public List<DictItemEntity> listDickCode(String dict_code, String dictCode) {
        QueryWrapper<DictItemEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(dict_code, dictCode).orderByAsc("sort");
        List<DictItemEntity> dictItemEntities = dictItemMapper.selectList(queryWrapper);
        return dictItemEntities;
    }

    /**
     * 获取指定字典code下拉
     *
     * @param dictCode
     * @return
     */
    @Override
    public List<KeyValue> select(String dictCode) {
        List<DictItemEntity> list = listDickCode("dict_code", dictCode);
        List<KeyValue> keyValues = list.stream().map(dictItemEntity -> {
            KeyValue keyValue = new KeyValue();
            keyValue.setId(dictItemEntity.getItemValue() + "");
            keyValue.setText(dictItemEntity.getItemName());
            return keyValue;
        }).collect(Collectors.toList());
        return keyValues;
    }

    /**
     * 获取指定code的数据字典下拉
     *
     * @param dictCodes
     * @return
     */
    @Override
    public Map<String, List<KeyValue>> selectCodes(List<String> dictCodes) {

        Map<String, List<KeyValue>> result = new HashMap<>(8);

        for (String dictCode : dictCodes) {
            String key = RedisKeyEnum.DICT_PREFIX.getKey() + dictCode;
            List<KeyValue> keyValues = cacheHelper.hashGet(key).entrySet().stream().map(entry -> {
                KeyValue keyValue = new KeyValue();
                keyValue.setId(entry.getKey());
                keyValue.setText(entry.getValue());
                return keyValue;
            }).collect(Collectors.toList());
            if (keyValues.size() != 0 && isNumeric(keyValues.get(0).getId())) {
                keyValues.sort(Comparator.comparing(KeyValue::getId));
            }
            result.put(dictCode, keyValues);
        }
        return result;
    }

    /**
     * 获取指定code的数据字典
     *
     * @param dictCodes
     * @return
     */
    @Override
    public Map<String, Map<String, String>> mapDictCodes(List<String> dictCodes) {
        Map<String, Map<String, String>> result = new HashMap<>(8);

        for (String dictCode : dictCodes) {
            String key = RedisKeyEnum.DICT_PREFIX.getKey() + dictCode;
            result.put(dictCode, cacheHelper.hashGet(key));
        }
        return result;
    }

    @Override
    public void processBeforeOperation(DictItemEntity entity, BaseOperationEnum operationEnum) {
        String key = RedisKeyEnum.DICT_PREFIX.getKey() + entity.getDictCode();
        switch (operationEnum) {
            case INSERT:
                LambdaQueryWrapper<DictItemEntity> wrapper = Wrappers.lambdaQuery();
                wrapper.eq(DictItemEntity::getItemName, entity.getItemName()).eq(DictItemEntity::getDictCode, entity.getDictCode());
                DictItemEntity dictItemEntity = dictItemMapper.selectOne(wrapper);
                if (dictItemEntity != null) {
                    throw BusinessExceptionBuilder.build(UserCode.DICT_ITEM_EXIST);
                }
                cacheHelper.hashSet(key, entity.getItemName(), entity.getItemValue());
                break;
            case UPDATE:
                cacheHelper.hashDel(key, entity.getItemName());
                break;
        }
    }

    @Override
    public void processAfterOperation(DictItemEntity entity, BaseOperationEnum operationEnum) {
        String key = RedisKeyEnum.DICT_PREFIX.getKey() + entity.getDictCode();
        switch (operationEnum) {
            case UPDATE:
                cacheHelper.hashSet(key, entity.getItemName(), entity.getItemValue());
                break;
            case DELETE:
                cacheHelper.hashDel(key, entity.getItemName());
                break;
        }
    }
}
